home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
xvisrc.zip
/
EX_CMDS1.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-28
|
19KB
|
860 lines
/* Copyright (c) 1990,1991,1992 Chris and John Downey */
#ifndef lint
static char *sccsid = "@(#)ex_cmds1.c 2.1 (Chris & John Downey) 7/29/92";
#endif
/***
* program name:
xvi
* function:
PD version of UNIX "vi" editor, with extensions.
* module name:
ex_cmds1.c
* module function:
File, window and buffer-related command functions
for ex (colon) commands.
* history:
STEVIE - ST Editor for VI Enthusiasts, Version 3.10
Originally by Tim Thompson (twitch!tjt)
Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
Heavily modified by Chris & John Downey
***/
#include "xvi.h"
#ifdef MEGAMAX
overlay "ex_cmds1"
#endif
static char **files; /* list of input files */
static int numfiles; /* number of input files */
static int curfile; /* number of the current file */
char *altfilename;
static long altfileline;
static char nowrtmsg[] = "No write since last change (use ! to override)";
static char nowrtbufs[] = "Some buffers not written (use ! to override)";
static bool_t more_files P((void));
void
do_quit(window, force)
Xviwin *window;
bool_t force;
{
Xviwin *wp;
bool_t changed;
bool_t canexit;
if (force) {
canexit = TRUE;
} else {
/*
* See if any buffers remain modified and unwritten.
*/
changed = FALSE;
wp = window;
do {
if (is_modified(wp->w_buffer)) {
changed = TRUE;
}
} while ((wp = next_window(wp)) != window);
if (changed) {
show_error(window, nowrtbufs);
canexit = FALSE;
} else {
canexit = ! more_files();
}
}
if (canexit) {
sys_exit(0);
}
}
/*
* Split the current window into two, leaving both windows mapped
* onto the same buffer.
*/
void
do_split_window(window)
Xviwin *window;
{
Xviwin *newwin;
newwin = split_window(window);
if (newwin == NULL) {
show_error(window, "No more windows!");
return;
}
map_window_onto_buffer(newwin, window->w_buffer);
/*
* Update the status line of the old window
* (since it will have been moved).
* Also update the window - this will almost certainly
* have no effect on the screen, but is necessary.
*/
show_file_info(window);
update_window(window);
/*
* Show the new window.
*/
init_sline(newwin);
update_window(newwin);
show_file_info(newwin);
/*
* Update the global window variable.
*/
curwin = newwin;
}
/*
* Open a new buffer window, with a possible filename arg.
*
* do_buffer() is responsible for updating the screen image for the
* old window, but not the new one, since we may want to move to a
* different location in the new buffer (e.g. for a tag search).
*/
bool_t
do_buffer(window, filename)
Xviwin *window;
char *filename;
{
Buffer *buffer;
Buffer *new;
Xviwin *newwin;
buffer = window->w_buffer;
if (window->w_nrows < (MINROWS + 1) * 2) {
show_error(window, "Not enough room!");
return(FALSE);
}
new = new_buffer();
if (new == NULL) {
show_error(window, "No more buffers!");
return(FALSE);
}
newwin = split_window(window);
if (newwin == NULL) {
free_buffer(new);
show_error(window, "No more windows!");
return(FALSE);
}
map_window_onto_buffer(newwin, new);
/*
* Update the status lines of each buffer.
*
* Even if (echo & e_SHOWINFO) is turned off, show_file_info()
* will always call update_sline(), which is what we really
* need here.
*
* Note that we don't need to call move_window_to_cursor() for
* the old window until it becomes the current window again.
*/
show_file_info(window);
init_sline(newwin);
if (filename != NULL) {
(void) do_edit(newwin, FALSE, filename);
} else {
new->b_filename = new->b_tempfname = NULL;
show_file_info(newwin);
}
update_window(window);
/*
* The current buffer (a global variable) has
* to be updated here. No way around this.
*/
curbuf = new;
curwin = newwin;
return(TRUE);
}
/*
* "close" (the current window).
*/
void
do_close_window(win, force)
Xviwin *win;
bool_t force;
{
Buffer *buffer;
Xviwin *best;
buffer = win->w_buffer;
if (is_modified(buffer) && !force && buffer->b_nwindows < 2) {
/*
* Don't close a modified buffer.
*/
show_error(win, nowrtmsg);
} else if (next_window(win) != win || !more_files()) {
Xviwin *w;
/*
* We can close this window if:
*
* (
* the buffer has not been modified
* or they are forcing the close
* or there are other windows onto this buffer
* )
* AND
* (
* there are other windows still open
* or there are no more files to be edited
* )
*/
/*
* Find an adjacent window to take up the screen
* space used by the one being closed.
*/
best = NULL;
for (w = next_window(win); w != win; w = next_window(w)) {
if (w->w_cmdline + 1 == win->w_winpos ||
w->w_winpos - 1 == win->w_cmdline ||
w->w_nrows == 0) {
/*
* We have found an adjacent window;
* if it is the first such, or if
* it is smaller than the previous
* best, it is now the new best.
*/
if (best == NULL || w->w_nrows < best->w_nrows) {
best = w;
}
}
}
if (best == NULL) {
sys_exit(0);
}
if (buffer->b_nwindows == 1 && buffer->b_filename != NULL) {
/*
* Before we free the buffer, save its filename.
*/
if (altfilename != NULL) {
free(altfilename);
}
altfilename = buffer->b_filename;
buffer->b_filename = NULL;
altfileline = lineno(buffer,
win->w_cursor->p_line);
}
/*
* Now "best" points to the smallest adjacent window;
* amalgamate the spaces used.
*/
if (best->w_winpos > win->w_winpos) {
best->w_winpos = win->w_winpos;
}
best->w_nrows += win->w_nrows;
best->w_cmdline = best->w_winpos + best->w_nrows - 1;
free_window(win);
if (buffer->b_nwindows == 0) {
free_buffer(buffer);
}
/*
* Have to update the globals "curbuf" and "curwin" here.
*/
curwin = best;
curbuf = best->w_buffer;
{
unsigned savecho;
savecho = echo;
/*
* Adjust position of new current window
* within buffer before updating it, to avoid
* wasting screen output - but don't do any
* scrolling at this stage because the old
* window is still on the screen.
*/
echo &= ~(e_CHARUPDATE | e_SHOWINFO | e_SCROLL);
move_window_to_cursor(curwin);
echo = savecho;
}
update_window(curwin);
show_file_info(curwin);
}
}
/*
* Close current window.
*
* If it is the last window onto the buffer, also close the buffer.
*
* If the buffer has been modified, we must write it out before closing it.
*/
void
do_xit(window)
Xviwin *window;
{
Buffer *buffer;
buffer = window->w_buffer;
if (is_modified(buffer) && buffer->b_nwindows < 2) {
if (buffer->b_filename != NULL) {
if (!writeit(window, buffer->b_filename,
(Line *) NULL, (Line *) NULL, FALSE)) {
return;
}
} else {
show_error(window, "No output file");
return;
}
}
do_close_window(window, FALSE);
}
/*
* Edit the given filename in the given buffer,
* replacing any current contents. Note that the
* screen is not updated, since there are routines
* which use this function before moving the cursor
* to a different position in the file.
*
* Returns TRUE for success, FALSE for failure.
*/
bool_t
do_edit(window, force, arg)
Xviwin *window;
bool_t force;
char *arg;
{
long line = 1; /* line # to go to in new file */
long nlines; /* no of lines read from file */
Line *head; /* start of list of lines */
Line *tail; /* last element of list of lines */
bool_t readonly; /* true if cannot write file */
Buffer *buffer;
Xviwin *wp;
buffer = window->w_buffer;
if (!force && is_modified(buffer)) {
show_error(window, nowrtmsg);
return(FALSE);
}
if (arg == NULL || arg[0] == '\0') {
/*
* No filename specified; we must already have one.
*/
if (buffer->b_filename == NULL) {
show_error(window, "No filename");
return(FALSE);
}
} else /* arg != NULL */ {
/*
* Filename specified.
*/
/*
* First detect a ":e" on the cur